package de.lgohlke.serializer;

import java.nio.ByteBuffer;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.serialize.ArraySerializer;

/**
 * <p>KryoSerializer class.</p>
 *
 * @author lars
 * @version $Id: $
 */
public class KryoSerializer<T> implements ISerializer<T>
{
  private final static Kryo kryo            = new Kryo();
  private static final int  MAX_BUFFER_SIZE = Double.valueOf(Math.pow(10, 5)).intValue();

  static
  {
    kryo.setRegistrationOptional(true);
    kryo.register(int[].class, new ArraySerializer(kryo));
  }

  /**
   * <p>serialize.</p>
   *
   * @param data a T object.
   * @param <T> a T object.
   * @return an array of byte.
   */
  public byte[] serialize(final T data)
  {
    ByteBuffer buffer = ByteBuffer.allocateDirect(MAX_BUFFER_SIZE);

    kryo.writeClassAndObject(buffer, data);
    byte[] bytes = new byte[buffer.position()];

    buffer.flip();
    buffer.get(bytes);

    return bytes;
  }

  /**
   * <p>deserialize.</p>
   *
   * @param data an array of byte.
   * @return a T object.
   */
  public T deserialize(final byte[] data)
  {
    ByteBuffer buffer = ByteBuffer.wrap(data);
    @SuppressWarnings("unchecked")
    T object = (T) kryo.readClassAndObject(buffer);

    return object;
  }
}
